package com.agileboot.domain.performance.submission.dto;

import cn.hutool.core.util.StrUtil;
import com.agileboot.common.utils.jackson.JacksonUtil;
import com.fasterxml.jackson.databind.JsonNode;

import java.text.SimpleDateFormat;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 绩效上报项Excel导出转换工具类
 */
public class SubmissionExcelConverter {

    private static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");

    // 状态映射
    private static final Map<String, String> STATUS_MAP = new HashMap<>();
    static {
        STATUS_MAP.put("DRAFT", "待提交");
        STATUS_MAP.put("PENDING_AUDIT", "审核中");
        STATUS_MAP.put("REJECTED", "已驳回");
        STATUS_MAP.put("APPROVED", "已批准");
    }

    // 审核级别映射
    private static final Map<Integer, String> AUDIT_LEVEL_MAP = new HashMap<>();
    static {
        AUDIT_LEVEL_MAP.put(0, "非审核状态");
        AUDIT_LEVEL_MAP.put(1, "待一审");
        AUDIT_LEVEL_MAP.put(2, "待二审");
        AUDIT_LEVEL_MAP.put(3, "待三审");
        AUDIT_LEVEL_MAP.put(4, "已完成");
    }

    /**
     * 将SubmissionDTO转换为SubmissionExcelDTO
     */
    public static SubmissionExcelDTO convert(SubmissionDTO dto) {
        if (dto == null) {
            return null;
        }

        SubmissionExcelDTO excelDTO = new SubmissionExcelDTO();
        
        // 基本字段
        excelDTO.setId(dto.getId());
        excelDTO.setAssessmentYear(dto.getAssessmentYear());
        excelDTO.setMainCategory(dto.getMainCategory());
        excelDTO.setSubCategory(dto.getSubCategory());
        excelDTO.setItemCategory(dto.getItemCategory());
        excelDTO.setTitle(dto.getTitle());
        excelDTO.setUserReportedScore(dto.getUserReportedScore());
        excelDTO.setCreatorName(dto.getCreatorName());
        excelDTO.setOwnerScore(dto.getOwnerScore());
        excelDTO.setOwnerName(dto.getOwnerName());
        excelDTO.setFirstReviewerName(dto.getFirstReviewerName());
        excelDTO.setSecondReviewerName(dto.getSecondReviewerName());
        excelDTO.setThirdReviewerName(dto.getThirdReviewerName());

        // 状态映射
        excelDTO.setStatus(STATUS_MAP.getOrDefault(dto.getStatus(), dto.getStatus()));

        // 审核级别映射
        if (dto.getCurrentAuditLevel() != null) {
            excelDTO.setCurrentAuditLevel(AUDIT_LEVEL_MAP.getOrDefault(dto.getCurrentAuditLevel(), 
                String.valueOf(dto.getCurrentAuditLevel())));
        } else {
            excelDTO.setCurrentAuditLevel("非审核状态");
        }

        // 日期格式化
        if (dto.getCreateTime() != null) {
            excelDTO.setCreateTime(DATE_FORMAT.format(dto.getCreateTime()));
        }
        if (dto.getThirdReviewTime() != null) {
            excelDTO.setThirdReviewTime(DATE_FORMAT.format(dto.getThirdReviewTime()));
        } else {
            excelDTO.setThirdReviewTime("无");
        }

        // 项目详情格式化
        excelDTO.setProjectDetails(formatProjectDetails(dto));

        // 证明材料格式化
        excelDTO.setEvidenceFiles(formatEvidenceFiles(dto.getFileList()));

        // 分配详情和分配材料格式化
        formatAllocationInfo(dto, excelDTO);

        return excelDTO;
    }

    /**
     * 格式化项目详情（从detailsJson解析）
     */
    private static String formatProjectDetails(SubmissionDTO dto) {
        if (StrUtil.isBlank(dto.getDetailsJson())) {
            return "";
        }

        try {
            JsonNode details = JacksonUtil.getObjectMapper().readTree(dto.getDetailsJson());
            if (details == null || !details.isObject()) {
                return "";
            }

            // 根据主类别和子类别生成动态字段
            String mainCategory = dto.getMainCategory();
            String subCategory = dto.getSubCategory();
            String itemCategory = dto.getItemCategory();

            List<String> detailLines = new ArrayList<>();

            // 其他工作量
            if ("其他工作量".equals(mainCategory)) {
                addDetailLine(detailLines, "工作内容描述", getJsonString(details, "workContent"));
                addDetailLine(detailLines, "开始日期", getJsonString(details, "startDate"));
                addDetailLine(detailLines, "结束日期", getJsonString(details, "endDate"));
                addDetailLine(detailLines, "工作成果", getJsonString(details, "workResult"));
                addDetailLine(detailLines, "备注", getJsonString(details, "remark"));
            }
            // 论文和学术报告
            else if ("论文和学术报告".equals(subCategory)) {
                addDetailLine(detailLines, "论文/报告题目", getJsonString(details, "paperTitle"));
                addDetailLine(detailLines, "期刊/会议名称", getJsonString(details, "journalOrConf"));
                addDetailLine(detailLines, "分区/类别", getJsonString(details, "partition"));
                addDetailLine(detailLines, "发表/报告日期", getJsonString(details, "publishDate"));
                addDetailLine(detailLines, "第一署名单位为中飞行院", formatBoolean(getJsonBoolean(details, "isFirstAffiliation")));
                addDetailLine(detailLines, "是否第一作者/通讯作者", formatBoolean(getJsonBoolean(details, "isFirstOrCorresponding")));
                addDetailLine(detailLines, "作者(按顺序)", getJsonString(details, "authors"));
            }
            // 科研项目/教研项目
            else if ("科研项目".equals(subCategory) || "教研项目".equals(subCategory)) {
                if (itemCategory != null && itemCategory.contains("横向项目到账经费")) {
                    addDetailLine(detailLines, "项目名称", getJsonString(details, "projectName"));
                    addDetailLine(detailLines, "到账经费(万元)", getJsonString(details, "amountWan"));
                    addDetailLine(detailLines, "到账年度", getJsonString(details, "year"));
                    addDetailLine(detailLines, "是否项目负责人", formatBoolean(getJsonBoolean(details, "isPI")));
                    addDetailLine(detailLines, "第一单位为中飞院", formatBoolean(getJsonBoolean(details, "firstUnit")));
                } else {
                    addDetailLine(detailLines, "项目名称", getJsonString(details, "projectName"));
                    addDetailLine(detailLines, "项目级别/类别", getJsonString(details, "projectLevel"));
                    addDetailLine(detailLines, "立项编号", getJsonString(details, "projectNo"));
                    addDetailLine(detailLines, "开始日期", getJsonString(details, "startDate"));
                    addDetailLine(detailLines, "结束日期", getJsonString(details, "endDate"));
                    addDetailLine(detailLines, "是否项目负责人", formatBoolean(getJsonBoolean(details, "isPI")));
                    addDetailLine(detailLines, "第一单位为中飞院", formatBoolean(getJsonBoolean(details, "firstUnit")));
                }
            }
            // 其他科研教研成果
            else if ("其他科研教研成果".equals(subCategory)) {
                if (itemCategory != null && itemCategory.contains("专利")) {
                    addDetailLine(detailLines, "专利名称", getJsonString(details, "patentTitle"));
                    addDetailLine(detailLines, "专利类型", getJsonString(details, "patentType"));
                    addDetailLine(detailLines, "授权号", getJsonString(details, "authNo"));
                    addDetailLine(detailLines, "授权日期", getJsonString(details, "authDate"));
                    addDetailLine(detailLines, "是否排名第一", formatBoolean(getJsonBoolean(details, "isFirstRank")));
                    addDetailLine(detailLines, "第一单位为中飞院", formatBoolean(getJsonBoolean(details, "firstUnit")));
                } else if (itemCategory != null && itemCategory.contains("著作")) {
                    addDetailLine(detailLines, "著作名称", getJsonString(details, "bookTitle"));
                    addDetailLine(detailLines, "ISBN/出版编号", getJsonString(details, "isbn"));
                    addDetailLine(detailLines, "出版社/出版单位", getJsonString(details, "publisher"));
                    addDetailLine(detailLines, "出版日期", getJsonString(details, "pubDate"));
                } else if (itemCategory != null && (itemCategory.contains("获奖") || itemCategory.contains("奖"))) {
                    addDetailLine(detailLines, "奖项名称", getJsonString(details, "awardName"));
                    addDetailLine(detailLines, "级别/等级", getJsonString(details, "awardLevel"));
                    addDetailLine(detailLines, "授奖单位", getJsonString(details, "awardingBody"));
                    addDetailLine(detailLines, "获奖日期", getJsonString(details, "awardDate"));
                }
            }
            // 学术兼职
            else if ("学术兼职".equals(subCategory)) {
                addDetailLine(detailLines, "兼职职务", getJsonString(details, "position"));
                addDetailLine(detailLines, "机构/期刊/协会", getJsonString(details, "organization"));
                addDetailLine(detailLines, "年度", getJsonString(details, "year"));
            }
            // 育人工作量
            else if ("育人工作量".equals(mainCategory)) {
                if ("学科竞赛".equals(subCategory)) {
                    addDetailLine(detailLines, "竞赛名称", getJsonString(details, "competitionName"));
                    addDetailLine(detailLines, "获奖等级", getJsonString(details, "award"));
                    addDetailLine(detailLines, "获奖日期", getJsonString(details, "awardDate"));
                    addDetailLine(detailLines, "学生姓名", getJsonString(details, "studentNames"));
                } else if ("学科竞赛组织与培训".equals(subCategory)) {
                    addDetailLine(detailLines, "活动名称", getJsonString(details, "activityName"));
                    addDetailLine(detailLines, "工作量(学时)", getJsonString(details, "hours"));
                    addDetailLine(detailLines, "完成日期", getJsonString(details, "date"));
                } else if ("科研论文".equals(subCategory)) {
                    addDetailLine(detailLines, "论文题目", getJsonString(details, "paperTitle"));
                    addDetailLine(detailLines, "期刊/会议", getJsonString(details, "journal"));
                    addDetailLine(detailLines, "学生第一作者", formatBoolean(getJsonBoolean(details, "isStudentFirst")));
                    addDetailLine(detailLines, "发表日期", getJsonString(details, "publishDate"));
                } else if ("科研项目".equals(subCategory)) {
                    addDetailLine(detailLines, "项目名称", getJsonString(details, "projectName"));
                    addDetailLine(detailLines, "参与情况/内容", getJsonString(details, "participation"));
                    addDetailLine(detailLines, "参与日期", getJsonString(details, "date"));
                } else if ("科研项目申报".equals(subCategory)) {
                    addDetailLine(detailLines, "项目名称", getJsonString(details, "projectName"));
                    addDetailLine(detailLines, "级别", getJsonString(details, "level"));
                    addDetailLine(detailLines, "申报/立项日期", getJsonString(details, "date"));
                } else if ("专利与学术著作".equals(subCategory)) {
                    addDetailLine(detailLines, "名称", getJsonString(details, "title"));
                    addDetailLine(detailLines, "类型(专利/著作/获奖)", getJsonString(details, "type"));
                    addDetailLine(detailLines, "完成日期", getJsonString(details, "date"));
                } else if ("毕业论文指导".equals(subCategory)) {
                    addDetailLine(detailLines, "学生姓名", getJsonString(details, "studentName"));
                    addDetailLine(detailLines, "论文题目", getJsonString(details, "topic"));
                    addDetailLine(detailLines, "完成日期", getJsonString(details, "finishDate"));
                } else if ("硕士研究生指导".equals(subCategory)) {
                    addDetailLine(detailLines, "学生姓名", getJsonString(details, "studentName"));
                    addDetailLine(detailLines, "阶段(开题/毕业)", getJsonString(details, "stage"));
                    addDetailLine(detailLines, "完成日期", getJsonString(details, "date"));
                } else if ("学术会议指导".equals(subCategory)) {
                    addDetailLine(detailLines, "会议名称", getJsonString(details, "conference"));
                    addDetailLine(detailLines, "报告题目", getJsonString(details, "reportTitle"));
                    addDetailLine(detailLines, "报告日期", getJsonString(details, "date"));
                } else if ("新教师指导".equals(subCategory)) {
                    addDetailLine(detailLines, "新教师姓名", getJsonString(details, "teacherName"));
                    addDetailLine(detailLines, "指导内容", getJsonString(details, "content"));
                    addDetailLine(detailLines, "完成日期", getJsonString(details, "date"));
                }
            }
            // 服务工作量
            else if ("服务工作量".equals(mainCategory)) {
                addDetailLine(detailLines, "服务事项/建设名称", getJsonString(details, "serviceName"));
                addDetailLine(detailLines, "阶段性成果说明", getJsonString(details, "stageResult"));
                addDetailLine(detailLines, "完成日期", getJsonString(details, "date"));
            }

            // 如果没有匹配到任何规则，则输出所有字段
            if (detailLines.isEmpty()) {
                details.fields().forEachRemaining(entry -> {
                    if (!"isMultiProject".equals(entry.getKey())) {
                        JsonNode valueNode = entry.getValue();
                        String value = valueNode != null ? (valueNode.isTextual() ? valueNode.asText() : valueNode.toString()) : null;
                        addDetailLine(detailLines, entry.getKey(), value);
                    }
                });
            }

            return String.join("\n", detailLines);
        } catch (Exception e) {
            // 解析失败时返回原始JSON
            return dto.getDetailsJson();
        }
    }

    /**
     * 从JsonNode获取字符串值
     */
    private static String getJsonString(JsonNode node, String key) {
        JsonNode valueNode = node.get(key);
        if (valueNode == null || valueNode.isNull()) {
            return null;
        }
        return valueNode.isTextual() ? valueNode.asText() : valueNode.toString();
    }

    /**
     * 从JsonNode获取布尔值
     */
    private static Boolean getJsonBoolean(JsonNode node, String key) {
        JsonNode valueNode = node.get(key);
        if (valueNode == null || valueNode.isNull()) {
            return null;
        }
        return valueNode.isBoolean() ? valueNode.asBoolean() : null;
    }

    /**
     * 格式化证明材料（从fileList解析）
     */
    private static String formatEvidenceFiles(String fileList) {
        if (StrUtil.isBlank(fileList)) {
            return "";
        }

        String[] files = fileList.split(";");
        return Arrays.stream(files)
                .map(String::trim)
                .filter(StrUtil::isNotBlank)
                .collect(Collectors.joining("\n"));
    }

    /**
     * 格式化分配详情和分配材料
     */
    private static void formatAllocationInfo(SubmissionDTO dto, SubmissionExcelDTO excelDTO) {
        if (StrUtil.isBlank(dto.getAllocationDetails())) {
            excelDTO.setAllocationDetails("");
            excelDTO.setAllocationMaterials("");
            return;
        }

        try {
            JsonNode parsed = JacksonUtil.getObjectMapper().readTree(dto.getAllocationDetails());
            List<String> allocationLines = new ArrayList<>();
            List<String> materialUrls = new ArrayList<>();

            if (parsed.isArray()) {
                // 旧格式：数组，每条含 userId/score/materials
                for (JsonNode item : parsed) {
                    JsonNode userIdNode = item.get("userId");
                    JsonNode scoreNode = item.get("score");
                    String userId = userIdNode != null ? userIdNode.asText() : "";
                    String score = scoreNode != null ? scoreNode.asText() : "0";
                    allocationLines.add(String.format("用户ID: %s, 分配分数: %s", userId, score));
                    
                    JsonNode materialsNode = item.get("materials");
                    if (materialsNode != null && materialsNode.isArray()) {
                        for (JsonNode material : materialsNode) {
                            if (material.isTextual()) {
                                materialUrls.add(material.asText());
                            }
                        }
                    }
                }
            } else if (parsed.isObject()) {
                // 新格式：{ materials: string[], items: [{userId,score}] }
                JsonNode itemsNode = parsed.get("items");
                if (itemsNode != null && itemsNode.isArray()) {
                    for (JsonNode item : itemsNode) {
                        JsonNode userIdNode = item.get("userId");
                        JsonNode scoreNode = item.get("score");
                        String userId = userIdNode != null ? userIdNode.asText() : "";
                        String score = scoreNode != null ? scoreNode.asText() : "0";
                        allocationLines.add(String.format("用户ID: %s, 分配分数: %s", userId, score));
                    }
                }
                
                JsonNode materialsNode = parsed.get("materials");
                if (materialsNode != null && materialsNode.isArray()) {
                    for (JsonNode material : materialsNode) {
                        if (material.isTextual()) {
                            materialUrls.add(material.asText());
                        }
                    }
                }
            }

            excelDTO.setAllocationDetails(String.join("\n", allocationLines));
            excelDTO.setAllocationMaterials(String.join("\n", materialUrls));
        } catch (Exception e) {
            // 解析失败时返回原始JSON
            excelDTO.setAllocationDetails(dto.getAllocationDetails());
            excelDTO.setAllocationMaterials("");
        }
    }

    /**
     * 添加详情行
     */
    private static void addDetailLine(List<String> lines, String label, String value) {
        if (value != null && !value.trim().isEmpty()) {
            lines.add(label + ": " + value);
        }
    }

    /**
     * 格式化布尔值
     */
    private static String formatBoolean(Boolean value) {
        if (value == null) {
            return "";
        }
        return value ? "是" : "否";
    }

    /**
     * 批量转换
     */
    public static List<SubmissionExcelDTO> convertList(List<SubmissionDTO> dtos) {
        if (dtos == null || dtos.isEmpty()) {
            return new ArrayList<>();
        }
        return dtos.stream()
                .map(SubmissionExcelConverter::convert)
                .collect(Collectors.toList());
    }
}

